package com.situ.day27;

import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.String;

public class ReflectDemo {

    @Test
    public void test1() {
        Student student = new Student();
        student.setName("张三");
        String name = student.getName();
        System.out.println(name);
    }

    @Test
    public void test2() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        // 拿到Student的 "字节码对象"
        Class clazz = Class.forName("com.situ.day27.Student");
        // 通过字节码对象拿到无参构造方法
        Constructor constructor = clazz.getConstructor();
        // 调用构造方法实例化一个对象
        // Student student = new Student();
        Student student = (Student) constructor.newInstance();
        // 通过反射拿到setName这个方法
        Method method1 = clazz.getMethod("setName", String.class);
        // student.setName("张三");
        // 通过反射调用方法
        method1.invoke(student, "李四");
        Method method2 = clazz.getMethod("getName");
        String name = (String) method2.invoke(student);
        System.out.println(name);
    }

    @Test
    public void testClass() throws ClassNotFoundException {
        // 1、Class.forName(类路径)
        Class clazz1 = Class.forName("com.situ.day27.Student");
        // 2、类型.class
        Class clazz2 = Student.class;
        // 3、对象.getClass()
        Student student = new Student();
        Class clazz3 = student.getClass();

        System.out.println(clazz1 == clazz2);
        System.out.println(clazz2 == clazz3);
        System.out.println(clazz1 == clazz3);
    }

    @Test
    public void testConstructor1() {
        Class clazz = Student.class;
        Constructor[] constructors = clazz.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }
    }

    @Test
    public void testConstructor2() {
        Class clazz = Student.class;
        Constructor[] constructors = clazz.getDeclaredConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
            System.out.println(constructor.getName());
            System.out.println(constructor.getModifiers());
        }
    }

    @Test
    public void testConstructor3() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class clazz = Student.class;
        Constructor constructor = clazz.getDeclaredConstructor(String.class);
        // java.lang.IllegalAccessException: Class com.situ.day27.ReflectDemo can not access a member
        // of class com.situ.day27.Student with modifiers "private"
        // 在反射面前，私有的属性、构造方法、普通方法都可以调用，但是要加上下面这句话
        constructor.setAccessible(true);
        Student student = (Student) constructor.newInstance("王五");
        System.out.println(student);
    }

    @Test
    public void testMethod() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class clazz = Student.class;
        // Constructor constructor = clazz.getConstructor();
        // Student student = (Student) constructor.newInstance();
        // 同过反射new无参构造方法可以简写成如下写法
        Student student = (Student) clazz.newInstance();
        Method setNameMethod = clazz.getMethod("setName", String.class);
        // student.setName("小张");
        setNameMethod.invoke(student, "小张");
        System.out.println(student);

    }

    @Test
    public void test11() {
        System.out.println(5&3);// 1
    }

}
